import { Graph, Shape } from "@antv/x6";
import { preCheckGraph, checkGraph, converter } from '../Plugins/ConductorConverter'

class X6FlowControl {
    graph!:Graph;

    constructor(){
        this.initWorkflowContainer();        
    }

    initWorkflowContainer(){
        this.graph = new Graph({
            container: document.getElementById("workflowContainer")!,
            autoResize: true,
            panning: true,
            mousewheel: true,
            background: {
                color: '#F2F7FA',
              },
            embedding: { // 开启嵌套
                enabled: true,
                findParent({ node }) { // sourceNode
                    const sourceNode = node;
                    const bbox = node.getBBox() 
                    // console.log('findParent bbox', node);
                    return this.getNodes().filter((node) => {
                        const data = node.getData<{ hasChildren: boolean, acceptChildrenIds:[] }>()
                        if (data && data.hasChildren) {
                            // 筛选下Target可接受的节点Id
                            let id: never = sourceNode!.data.id as never;
                            // console.log('sourceNodeId', id, data.acceptChildrenIds, data.acceptChildrenIds.indexOf(id));
                            if(data.acceptChildrenIds.indexOf(id)>=0){
                                const targetBBox = node.getBBox()
                                return bbox.isIntersectWithRect(targetBBox)
                            }else{
                                return false;
                            }
                        }
                        return false
                    })
                },
            },
            connecting: {
                allowBlank: false, // 是否允许连接到画布空白位置的点，默认为 true。
                allowLoop: false, // 是否允许创建循环连线，即边的起始节点和终止节点为同一节点，默认为 true。
                allowNode: true, // 是否允许边连接到节点（非节点上的连接桩），默认为 true。
                allowEdge: false, // 是否允许边连接到另一个边，默认为 true。
                allowPort: false, // 是否允许边连接到连接桩，默认为 true。
                allowMulti: false, // 是否允许在相同的起始节点和终止之间创建多条边，默认为 true。
            },
        });
        this.initGraphEvent();
        // 边的事件行为
        this.initEdgeContext();
    }

    initGraphEvent() {
        this.graph.on('node:embedded', (e) => {
            console.log('node:embedded', e.currentParent);
            // 向上递归，如果都是容器，都需要fit下。
            let depth = (node:any)=>{
                if(node && node.data && node.data.hasChildren) {
                    node.fit({
                        "padding":{
                            left: 100,
                            top: 50,
                            right: 100,
                            bottom: 50
                        }
                    });
                }
                // console.log('node._parent', node._parent);
                if(node._parent != undefined) {
                    depth(node._parent)
                }
            }
            depth(e.currentParent);
        });

        // 有些节点只能用于某些节点内，所以只能在node:added事件中进行判断。
        this.graph.once("node:added", ({ node, index, options }) => {
            console.log("node:added", node);
            if(node && node.data && node.data.id && node.data.id == "ForkGroupNode") {
                console.log('node["_parent"]', node['_parent']);
                if(node['_parent'] != undefined && node['_parent'].data && node['_parent'].data.id && node['_parent'].data.id == 'ForkNode'){
                    // this.graph.addNode(node);
                }else{
                    console.log('父节点非ForkNode');
                    this.graph.removeNode(node);
                    alert('[并行分组]节点只能用于[并行]节点中');
                }
            }
        });
    }

    initEdgeContext() {
        // 双击 删除边
        this.graph.on("edge:dblclick", ({ edge }) => {
            console.log("edge:dblclick", edge);
            console.log("删除边", edge);
            if(confirm("确定删除边")){
                this.graph.removeEdge(edge);
            }
        });

        this.graph.on("edge:added", ({edge})=>{
            console.log("edge:added", edge);
            edge.attr("line/stroke", "#409eff");
        })
    }

    
    save() {
        let jsonObj = this.graph.toJSON();
        console.log('jsonObj', jsonObj);
        
        if(preCheckGraph(this.graph, jsonObj) && checkGraph(jsonObj)){
            let DSL = converter(this.graph, jsonObj);
            console.log('jsonObj', jsonObj, DSL);
        }
    }
}

export default X6FlowControl;